package com.pithypan.controller;


import com.pithypan.common.Constants;
import com.pithypan.common.FileDelFlagEnums;
import com.pithypan.common.ResponseCodeEnum;
import com.pithypan.common.exceptionHandler.MyException;
import com.pithypan.common.utils.R;
import com.pithypan.common.utils.StringTools;
import com.pithypan.convert.FileShareConvert;
import com.pithypan.dto.SessionShareDto;
import com.pithypan.dto.SessionWebUserDto;
import com.pithypan.entity.FileInfo;
import com.pithypan.entity.FileShare;
import com.pithypan.entity.UserInfo;
import com.pithypan.service.FileInfoService;
import com.pithypan.service.FileShareService;
import com.pithypan.service.UserInfoService;
import com.pithypan.vo.FileInfoQuery;
import com.pithypan.vo.FileShareVo;
import com.pithypan.vo.PaginationResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;


/**
 * 文件外部分享
 */
@RestController
@RequestMapping("/showShare")
public class WebShareController extends CommonFileController {

    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private FileInfoService fileInfoService;
    @Autowired
    private FileShareService fileShareService;


    /**
     * 获取已提取了的分享文件
     * @param session
     * @param shareId
     * @return
     */
    @RequestMapping("/getShareLoginInfo")
    public R getShareLoginInfo(HttpSession session, String shareId) {
        //从session中获取已提取了的分享文件
        SessionShareDto sessionShareDto = (SessionShareDto) session.getAttribute(Constants.SESSION_SHARE_KEY + shareId);
        if (sessionShareDto == null) {   //证明未提取
            return R.ok().data(null);
        }

        FileShareVo fileShareVo = getShareInfoCommon(shareId);
        //判断是否已登陆，且文件是否是当前用户分享的
        SessionWebUserDto webUserDto = (SessionWebUserDto) session.getAttribute(Constants.SESSION_KEY);
        if (webUserDto != null && webUserDto.getUserId().equals(sessionShareDto.getShareUserId())) {
            fileShareVo.setCurrentUser(true);
        } else {
            fileShareVo.setCurrentUser(false);
        }

        return R.ok().data("fileShare", fileShareVo);
    }


    /**
     * 根据id查询分享文件
     * @param shareId
     * @return
     */
    @RequestMapping("/getShareInfo")
    public R getShareInfo(String shareId) {
        return R.ok().data("fileShare", getShareInfoCommon(shareId));
    }


    /**
     * 校验提取码，并提取分享文件
     * @param session
     * @param shareId
     * @param code     前端用户输入的提取码
     * @return
     */
    @RequestMapping("/checkShareCode")
    public R checkShareCode(HttpSession session, String shareId, String code) {
        SessionShareDto sessionShareDto = fileShareService.checkShareCode(shareId, code); //校验提取码
        session.setAttribute(Constants.SESSION_SHARE_KEY + shareId, sessionShareDto);   //已提取则存入session
        return R.ok().data(null);
    }


    /**
     * 分页查询文件（非shareId的子文件或孙文件不得查询）
     * @param session
     * @param shareId   分享文件shareId
     * @param filePid   要进入的目录fileId
     * @return
     */
    @RequestMapping("/loadFileList")
    public R loadFileList(HttpSession session, String shareId, String filePid) {
        //校验文件是否已提取，且未过期
        SessionShareDto sessionShareDto = checkShare(session, shareId);

        FileInfoQuery query = new FileInfoQuery();
        //如果filePid不为空，且filePid不是根目录
        if (!StringTools.isEmpty(filePid) && !Constants.ZERO_STR.equals(filePid)) {
            //校验 filePid 是否是 分享文件 的子文件或孙文件
            fileInfoService.checkRootFilePid(sessionShareDto.getFileId(), sessionShareDto.getShareUserId(), filePid);
            query.setFilePid(filePid);                     //添加查询条件：FilePid
        } else{
            query.setFileId(sessionShareDto.getFileId());  //添加查询条件：FileId
        }

        query.setUserId(sessionShareDto.getShareUserId());  //设置用户id
        query.setOrderBy("last_update_time desc");          //根据更新时间降序排序
        query.setDelFlag(FileDelFlagEnums.USING.getFlag()); //0:删除 1:回收站 2:正常
        PaginationResultVo result = fileInfoService.findListByPage(query);
        return R.ok().data("dataList", result);
    }


    /**
     * 将分享文件保存到网盘
     * @param session
     * @param shareId       分享文件shareId
     * @param shareFileIds  选中的文件的fileId（分享的可能是一个目录，里面有多个文件）
     * @param myFolderId    保存的目的地
     * @return
     */
    public R saveShare(HttpSession session, String shareId, String shareFileIds, String myFolderId) {
        //校验文件是否已提取，且未过期
        SessionShareDto sessionShareDto = checkShare(session, shareId);
        //从session中获取登陆用户信息
        SessionWebUserDto webUserDto = (SessionWebUserDto) session.getAttribute(Constants.SESSION_KEY);

        //判断文件是否是当前用户分享的
        if (sessionShareDto.getShareUserId().equals(webUserDto.getUserId())) {
            throw new MyException(907, "无法保存自己分享的文件");
        }

        //将分享文件保存到网盘
        fileInfoService.saveShare(sessionShareDto.getFileId(), shareFileIds, myFolderId, sessionShareDto.getShareUserId(), webUserDto.getUserId());
        return R.ok().data(null);
    }


    /**
     * 根据 id串 获取相对应的目录
     * @param session
     * @param path       路径, id串用 / 字符分隔（例：wuvakndsa/aknababa）
     * @return
     */
    @RequestMapping("/getFolderInfo")
    public R getFolderInfo(HttpSession session, String shareId, String path) {
        //校验文件是否已提取，且未过期
        SessionShareDto sessionShareDto = checkShare(session, shareId);
        return super.getFolderInfo(sessionShareDto.getShareUserId(), path);
    }


    /**
     * 视频文件分段预览
     * @param response
     * @param shareId
     * @param fileId  视频文件id 或 视频分片名称（如：QZeD5BDF9w_0000.ts）
     */
    @RequestMapping("/ts/getVideoInfo/{shareId}/{fileId}")
    public void getVideo(HttpServletResponse response, HttpSession session,
                         @PathVariable("shareId") String shareId, @PathVariable("fileId") String fileId) {
        //校验文件是否已提取，且未过期
        SessionShareDto sessionShareDto = checkShare(session, shareId);
        super.getFile(response, fileId, sessionShareDto.getShareUserId());
    }


    /**
     * 其它文件 预览
     * @param response
     * @param fileId
     */
    @RequestMapping("/getFile/{shareId}/{fileId}")
    public void getFile(HttpServletResponse response, HttpSession session,
                        @PathVariable("shareId") String shareId, @PathVariable("fileId") String fileId) {
        //校验文件是否已提取，且未过期
        SessionShareDto sessionShareDto = checkShare(session, shareId);
        super.getFile(response, fileId, sessionShareDto.getShareUserId());
    }


    /**
     * 创建下载
     * @param fileId 需下载的文件
     * @return
     */
    @RequestMapping("/createDownloadUrl/{shareId}/{fileId}")
    public R createDownloadUrl(HttpSession session,
                               @PathVariable("shareId") String shareId, @PathVariable("fileId") String fileId) {
        //校验文件是否已提取，且未过期
        SessionShareDto sessionShareDto = checkShare(session, shareId);
        return super.createDownloadUrl(sessionShareDto.getShareUserId(), fileId);
    }


    /**
     * 文件下载
     * @param request
     * @param response
     * @param code
     * @throws Exception
     */
    @RequestMapping("/download/{code}")
    public void download(HttpServletRequest request, HttpServletResponse response, @PathVariable("code") String code) throws Exception {
        super.download(request, response, code);
    }



//---------------------------------------------------------------------------------------------

    //根据shareId获取分享文件
    private FileShareVo getShareInfoCommon(String shareId) {

        FileShare share = fileShareService.getFileShareByShareId(shareId);
        //判断分享文件是否不存在，或已过期
        if (share == null || (share.getExpireTime() != null && new Date().after(share.getExpireTime()))) {
            throw new MyException(ResponseCodeEnum.CODE_902.getCode(), ResponseCodeEnum.CODE_902.getMsg());
        }

        FileInfo fileInfo = fileInfoService.getFileInfoByFileIdAndUserId(share.getFileId(), share.getUserId());
        //判断文件是否不存在，或非正常状态
        if (fileInfo == null || !FileDelFlagEnums.USING.getFlag().equals(fileInfo.getDelFlag())) {
            throw new MyException(ResponseCodeEnum.CODE_902.getCode(), ResponseCodeEnum.CODE_902.getMsg());
        }

        //查询用户
        UserInfo userInfo = userInfoService.getUserInfoByUserId(share.getUserId());

        FileShareVo fileShareVo = FileShareConvert.INSTANCE.entity2vo(share);
        fileShareVo.setFileName(fileInfo.getFileName());  //设置文件名
        fileShareVo.setNickName(userInfo.getNickName());  //设置分享用户名
        fileShareVo.setAvatar(userInfo.getQqAvatar());    //设置分享用户头像
        fileShareVo.setUserId(userInfo.getUserId());
        return fileShareVo;
    }


    //校验文件是否已提取，且未过期
    private SessionShareDto checkShare(HttpSession session, String shareId) {
        //从session中获取已提取了的分享文件
        SessionShareDto sessionShareDto = (SessionShareDto) session.getAttribute(Constants.SESSION_SHARE_KEY + shareId);
        if (sessionShareDto == null) {  //证明未提取
            throw new MyException(ResponseCodeEnum.CODE_906.getCode(), ResponseCodeEnum.CODE_906.getMsg());
        }

        //判断分享文件是否已过期
        if (sessionShareDto.getExpireTime() != null && new Date().after(sessionShareDto.getExpireTime())) {
            throw new MyException(ResponseCodeEnum.CODE_902.getCode(), ResponseCodeEnum.CODE_902.getMsg());
        }
        return sessionShareDto;
    }
}
